package itdep.jsf.internal;

import ga.i18n.Translatable;
import ga.i18n.Translator;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import javax.faces.context.FacesContext;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Ivan Khalopik
 * @version $Revision: 34 $ $Date: 2010-06-20 09:57:55 +0000 (Sun, 20 Jun 2010) $
 */
public class TranslationELResolver extends ELResolver {
	private Translator translator;

	private boolean supports(Object base) {
		return base != null && base instanceof Translatable;
	}

	@Override
	public Object getValue(ELContext elContext, Object base, Object property) {
		if (supports(base)) {
			final Map<String, String> translations = getTranslator().translate((Translatable) base, JSFUtils.getLocale());
			return translations.get(String.valueOf(property));
		}
		return null;
	}

	@Override
	public Class getType(ELContext elContext, Object base, Object property) {
		return supports(base) ? String.class : null;
	}

	@Override
	public void setValue(ELContext elContext, Object base, Object property, Object value) {
		if (supports(base)) {
			throw new PropertyNotWritableException("Variable '" + property + "' is not writable");
		}
	}

	@Override
	public boolean isReadOnly(ELContext elContext, Object base, Object property) {
		return supports(base);
	}

	@Override
	public Iterator getFeatureDescriptors(ELContext elContext, Object base) {
		return null;
	}

	@Override
	public Class getCommonPropertyType(ELContext elContext, Object o) {
		return Object.class;
	}

	private Translator getTranslator() {
		if (translator == null) {
			translator = getWebApplicationContext().getBean(Translator.class);
		}
		return translator;
	}

	private static WebApplicationContext getWebApplicationContext() {
		return FacesContextUtils.getRequiredWebApplicationContext(FacesContext.getCurrentInstance());
	}
}
